package cn.wolfcode.crm.shiro;

import cn.wolfcode.crm.domain.Employee;
import cn.wolfcode.crm.mapper.EmployeeMapper;
import cn.wolfcode.crm.mapper.PermissionMapper;
import cn.wolfcode.crm.mapper.RoleMapper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Set;

@Component("MyRealm")
public class MyRealm extends AuthorizingRealm {
    @Override
    public String getName() {
        return "MyRealm";
    }

    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private PermissionMapper permissionMapper;

    //在容器中的配置的凭证匹配器注入给当前的realm对象
    //在该realm中使用指定的凭证匹配器来完成密码匹配的操作
    @Autowired
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        super.setCredentialsMatcher(credentialsMatcher);
    }

    //获取认证信息
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        String username = (String) token.getPrincipal();
        Employee emp = employeeMapper.selectByUsername(username);
        if (emp == null) {
            return null;
        }
        //emp 相当于共享到session 后期要用到
        return new SimpleAuthenticationInfo(emp, emp.getPassword(), ByteSource.Util.bytes(emp.getName()), this.getName());
        //如果账号正确 返回一个 AuthenticationInfo 对象

    }

    //获取授权信息
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();

        //获取当前登录的用户  两种方法
//        Employee currentEmp = (Employee)SecurityUtils.getSubject().getPrincipal();
        Employee currentEmp = (Employee) principals.getPrimaryPrincipal();
        //是否是超管 role  expression
        if (currentEmp.isAdmin()) {
            info.addRole("admin");//超管这个角色只能叫admin
            info.addStringPermission("*:*");
            return info;
        }
        //不是超管  获取当前用户拥有的角色和权限
        List<String> sns = roleMapper.selectSnByEmployeeId(currentEmp.getId());
        //info.addRole(roles);
        Set<String> expressions = permissionMapper.selectExpressionByEmpId(currentEmp.getId());
        info.addStringPermissions(expressions);
        return info;
    }

    //放在容器中了
    public void clearCached() {
        PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
        super.clearCache(principals);
    }

}
